﻿
Перем Токены;
Перем Исходник;
Перем ТаблицаТокенов;
Перем КлючевыеСлова;

Перем Результат;

Процедура Открыть(Парсер, Параметры) Экспорт
	Токены = Парсер.Токены();
	Исходник = Парсер.Исходник();
	ТаблицаТокенов = Парсер.ТаблицаТокенов();
	КлючевыеСлова = Парсер.КлючевыеСлова();
	Результат.Очистить();
КонецПроцедуры // Открыть()

Функция Закрыть() Экспорт
	
	Результат.Добавить(
	"<!DOCTYPE html>
	|<html>
	|<head>
	|    <meta http-equiv='Content-Тип' content='text/html; charset=utf-8'>
	|    <title>Исходник</title>
	|    <style type='text/css'>
	|html {
	|	scroll-behavior: smooth;
	|	margin-bottom: 25%;
	|}
	|
	|body {
	|	font-family: Menlo, monospace;
	|	font-size: 12px;
	|}
	|
	|.keyword, .special {
	|	color: red;
	|}
	|
	|.issue {
	|	text-decoration-line: underline;
	|	text-decoration-style: wavy;
	|	text-decoration-color: red;
	|}
	|
	|.comment {
	|	color: rgb(204, 204, 204);
	|}
	|
	|.string {
	|	color: rgb(202, 147, 121);
	|}
	|
	|.codeline {
	|	white-space: pre;
	|}
	|
	|.error {
	|	color: rgb(255, 255, 255);
	|	background-color: chocolate;
	|}
	|
	|table {
	|    border-spacing: 0;
	|    border-collapse: collapse;
	|    tab-size: 4;
	|}
	|
	|.linum {
	|	white-space: pre;
	|	text-align: right;
	|	color: rgba(27,31,35,.3);
	|	padding-right: 10px;
	|	padding-left: 10px;
	|	user-select: none;
	|}
	|
	|    </style>
	|</head>
	|<body>
	|    <div>
	|        <table>"
	);
	
	КоличествоТокенов = ТаблицаТокенов.Количество();
	
	КоличествоСтрок = ТаблицаТокенов[ТаблицаТокенов.Количество()-2].НомерСтроки;
	
	Индекс = 1;
	
	Позиция = 1;
	
	Для НомерСтроки = 1 По КоличествоСтрок Цикл
		
		Результат.Добавить(СтрШаблон(""
		"            <tr>
		|                <td class='linum'>%1</td>
		|                <td class='codeline'>",
		Формат(НомерСтроки, "ЧГ=")
		));
		
		Пока Индекс < КоличествоТокенов
			И ТаблицаТокенов[Индекс].НомерСтроки <= НомерСтроки Цикл
			
			Токен = ТаблицаТокенов[Индекс]; 
			
			Промежуток = Токен.Позиция - Позиция;
			Если Промежуток > 0 Тогда
				Пробелы = Сред(Исходник, Позиция, Промежуток);
				ПозицияНачалаСтроки = СтрНайти(Пробелы, Символы.ПС, НаправлениеПоиска.СКонца);
				Если ПозицияНачалаСтроки > 0 Тогда
					Позиция = Позиция + ПозицияНачалаСтроки;
					Промежуток = Токен.Позиция - Позиция;
				КонецЕсли;
				Если Промежуток > 0 Тогда
					Если ПустаяСтрока(Пробелы) Тогда
						Добавить(Позиция, Промежуток);
					Иначе
						Добавить(Позиция, Промежуток, "comment");
					КонецЕсли; 
				КонецЕсли; 
			КонецЕсли;
			Позиция = Токен.Позиция + Токен.Длина;
			
			Если КлючевыеСлова.Свойство(Токен.Токен) И ТаблицаТокенов[Индекс - 1].Токен <> Токены.Точка Тогда
				Добавить(Токен.Позиция, Токен.Длина, "keyword");
			ИначеЕсли Токен.Токен = Токены.Комментарий Тогда	
				Добавить(Токен.Позиция, Токен.Длина, "comment");
			ИначеЕсли Токен.Токен = Токены.Строка
				Или Токен.Токен = Токены.НачалоСтроки
				Или Токен.Токен = Токены.ПродолжениеСтроки
				Или Токен.Токен = Токены.ОкончаниеСтроки Тогда	
				Добавить(Токен.Позиция, Токен.Длина, "string");
			ИначеЕсли Токен.Токен = Токены.Точка
				Или Токен.Токен = Токены.Запятая
				Или Токен.Токен = Токены.ТочкаСЗапятой
				Или Токен.Токен = Токены.ЛеваяКруглаяСкобка
				Или Токен.Токен = Токены.ПраваяКруглаяСкобка
				Или Токен.Токен = Токены.ЛеваяКвадратнаяСкобка
				Или Токен.Токен = Токены.ПраваяКвадратнаяСкобка Тогда	
				Добавить(Токен.Позиция, Токен.Длина, "special");
			Иначе	
				Добавить(Токен.Позиция, Токен.Длина);
			КонецЕсли;
			
			Индекс = Индекс + 1;
			
		КонецЦикла; 
		
		Результат.Добавить("</td>"
		"            </tr>"
		);
		
	КонецЦикла; 
	
	Результат.Добавить(""
	"        </table>
	|    </div>
	|</body>"
	);
	
	Возврат СтрСоединить(Результат);
КонецФункции // Закрыть()

Функция Добавить(Знач Начало, Знач Длина, Класс = Неопределено)	
	Текст = БезопасныйHTML(Сред(Исходник, Начало, Длина));
	Если Класс <> Неопределено Тогда
		Результат.Добавить(СтрШаблон("<span class='%1'>%2</span>", Класс, Текст));
	Иначе
		Результат.Добавить(Текст);
	КонецЕсли; 	
КонецФункции 

Функция БезопасныйHTML(Текст)
	
	// нельзя так заменять
	// надо за один проход
	
	//Текст = СтрЗаменить(Текст, "&quot;", "&amp;quot;");
	//Текст = СтрЗаменить(Текст, "&amp;", "&amp;amp;");
	//Текст = СтрЗаменить(Текст, "&lt;", "&amp;lt;");
	//Текст = СтрЗаменить(Текст, "&gt;", "&amp;gt;");
	Текст = СтрЗаменить(Текст, "<", "&lt;");
	Текст = СтрЗаменить(Текст, ">", "&gt;");
	Текст = СтрЗаменить(Текст, """", "&quot;");
	
	Возврат Текст;
	
КонецФункции 

Функция Подписки() Экспорт
	Перем Подписки;
	Подписки = Новый Массив;
	Возврат Подписки;
КонецФункции // Подписки()

Результат = Новый Массив;